//////////////////////////////////////////////////////////////////////////////
//
//  Created by Philip Mulcahy on 03/01/2013.
//  Copyright (c) 2012 Philip Mulcahy. All rights reserved.
//
//  This file is part of the note-recog library.
//
//  note-recog is free software: you can redistribute it and/or modify
//  it under the terms of version 3 of the GNU Lesser General Public License 
//  as published by the Free Software Foundation.
//
//  note-recog is distributed is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with note-recog.  If not, see <http://www.gnu.org/licenses/>.
//
//////////////////////////////////////////////////////////////////////////////


#ifndef note_recog_Filter_h
#define note_recog_Filter_h

template<typename T>
class IFilter
{
public:
    virtual T output(const T& input) = 0;
};


template<typename T>
class ExponentialMovingAverage : public IFilter<T>
{
private:
    const T _alpha;
    T _last;
    
public:
    ExponentialMovingAverage(const T& alpha) 
    : _alpha(alpha), _last(static_cast<T>(0))
    {}
    
    virtual T output(const T& input)
    {
        const T preservation_factor = static_cast<T>(1) - _alpha;
        _last *= preservation_factor;
        _last += _alpha * input;
        return _last;
    }
};

template<typename T>
class ExponentialDecayEnvelope : public IFilter<T>
{
private:
    const T _decay_factor;
    T _last;
    
public:
    ExponentialDecayEnvelope(const T& decay_factor)
    : _decay_factor(decay_factor),
      _last(static_cast<T>(0))
    {}
    
    virtual T output(const T& input)
    {
        _last *= _decay_factor;
        if( input > _last )
        {
            _last = input;
        }
        return _last;
    }
};

#endif
